package com.ppt.android.base.utils

//import com.alibaba.android.arouter.launcher.ARouter
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.util.Log
import android.widget.Toast
import androidx.core.content.FileProvider
import com.ppt.android.BuildConfig
import com.ppt.android.base.BaseApplication
import com.ppt.android.base.utils.uri.UriUtils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import java.io.File

/**
 * 使用 Flow 做的简单的轮询
 * 请使用单独的协程来进行管理该 Flow
 * Flow 仍有一些操作符是实验性的 使用时需添加 @InternalCoroutinesApi 注解
 * @param intervals 轮询间隔时间/毫秒
 * @param block 需要执行的代码块
 */
suspend fun startPolling(intervals: Long, block: () -> Unit) {
    flow {
        while (true) {
            delay(intervals)
            emit(0)
        }
    }
        .catch { Log.e("flow", "startPolling: $it") }
        .flowOn(Dispatchers.Main)
        .collect { block.invoke() }
}
/**************************************************************************************************/

/**
 * 发送普通EventBus事件
 */
fun sendEvent(event: Any) = EventBusUtils.postEvent(event)


/**************************************************************************************************/
/**
 * toast
 * @param msg String 文案
 * @param duration Int 时间
 */
fun toast(msg: String, duration: Int = Toast.LENGTH_SHORT) {
    ToastUtils.showToast(msg, duration)
}

/**
 * toast
 * @param msgId Int String资源ID
 * @param duration Int 时间
 */
fun toast(msgId: Int, duration: Int = Toast.LENGTH_SHORT) {
    ToastUtils.showToast(msgId, duration)
}

/**
 * 获取文件路径适配Android 11
 *
 * @return
 */
fun getRootDirectory(ctx: Context,directoryName: String): String{
    return if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q)
        ctx.getExternalFilesDir(null)?.absolutePath + File.separator + ctx.packageName + File.separator + directoryName
    else
        Environment.getExternalStorageDirectory().absolutePath + File.separator + ctx.packageName + File.separator + directoryName
}

fun isAndroidS(): Boolean {
    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU
}

fun getApp(): Context {
    return BaseApplication.context
}

/**
 * Return the application's version name.
 *
 * @return the application's version name
 */
fun getAppVersionName(): String? {
    return getAppVersionName(getApp().packageName)
}

/**
 * Return the application's version name.
 *
 * @param packageName The name of the package.
 * @return the application's version name
 */
fun getAppVersionName(packageName: String?): String? {
    return if (UriUtils.isSpace(packageName)) "" else try {
        val pm = getApp().packageManager
        val pi = pm.getPackageInfo(packageName!!, 0)
        if (pi == null) "" else pi.versionName
    } catch (e: PackageManager.NameNotFoundException) {
        e.printStackTrace()
        ""
    }
}

fun getAppVersionCode(): Int {
    return getAppVersionCode(getApp().packageName)
}

/**
 * Return the application's version code.
 *
 * @param packageName The name of the package.
 * @return the application's version code
 */
fun getAppVersionCode(packageName: String?): Int {
    return if (UriUtils.isSpace(packageName)) -1 else try {
        val pm = getApp().packageManager
        val pi = pm.getPackageInfo(packageName!!, 0)
        pi?.versionCode ?: -1
    } catch (e: PackageManager.NameNotFoundException) {
        e.printStackTrace()
        -1
    }
}

/**
 * Install the app.
 *
 * Target APIs greater than 25 must hold
 * `<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />`
 *
 * @param file The file.
 */
fun installApp(file: File?) {
    val installAppIntent = getInstallAppIntent(file) ?: return
    getApp().startActivity(installAppIntent)
}

/**
 * Return the intent of install app.
 *
 * Target APIs greater than 25 must hold
 * `<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />`
 *
 * @param file The file.
 * @return the intent of install app
 */
fun getInstallAppIntent(file: File?): Intent? {
    if (!UriUtils.isFileExists(file)) return null
    val uri: Uri
    uri = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
        Uri.fromFile(file)
    } else {
        val authority = getApp().packageName + ".fileProvider"
        FileProvider.getUriForFile(
            getApp(), authority,
            file!!
        )
    }
    return getInstallAppIntent(uri)
}

fun getInstallAppIntent(uri: Uri?): Intent? {
    if (uri == null) return null
    val intent = Intent(Intent.ACTION_VIEW)
    val type = "application/vnd.android.package-archive"
    intent.setDataAndType(uri, type)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
    }
    return intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}

fun isDebug(): Boolean{
    val isDebug = when(BuildConfig.BUILD_TYPE){
        "debug"-> true
        "beta" -> true
        "release" -> false
        else -> false
    }
    return isDebug
}

